package com.sfd.message.remind.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.ChineseDate;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sfd.message.remind.constant.enums.FestivalDefaultType;
import com.sfd.message.remind.entity.Festival;
import com.sfd.message.remind.entity.FestivalDefault;
import com.sfd.message.remind.mapper.FestivalMapper;
import com.sfd.message.remind.module.Result;
import com.sfd.message.remind.service.FestivalDefaultService;
import com.sfd.message.remind.service.FestivalService;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.BufferedWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

/**
 * @author haden
 * @date 2022/9/7 14:32
 **/
@Service
public class FestivalServiceImpl extends ServiceImpl<FestivalMapper, Festival> implements FestivalService {
    @Resource
    FestivalDefaultService festivalDefaultService;

    @SneakyThrows
    @Override
    public Result<List<Festival>> getFestival(Integer years) {
        List<Festival> festivals = lambdaQuery().list();
        if (CollectionUtil.isEmpty(festivals)) {
            return Result.success();
        }
        //写到文件中
        String fileName = "D:\\tmp\\festival.txt";
        Path path = Paths.get(fileName);
        try(BufferedWriter writer = Files.newBufferedWriter(path, StandardCharsets.UTF_8)){
            writer.write(JSONObject.toJSONString(festivals));
        }
        return Result.success(JSONObject.toJSONString(festivals));
    }

    @Override
    public Result<String> createFestival(Integer years) {
        if (null == years) {
            return Result.paramError("years不能为空");
        }
        //现在时间
        DateTime now = DateTime.now();
        //获取x年后的时间
        DateTime end = DateUtil.offsetMonth(now, years * 12);
        //新历节日
        getPublicFestival(years);
        //农历节日
        getChinesFestival(end);
        return Result.success();
    }

    /**
     * 新历节日获取
     *
     * @param years 查询范围
     */
    private void getPublicFestival(Integer years) {
        List<Festival> festivals = new ArrayList<>();
        List<FestivalDefault> festivalDefaults = festivalDefaultService.getByType(FestivalDefaultType.publication.getKey());

        String yearStr = DateUtil.format(new Date(), "yyyy");
        int year = Integer.parseInt(yearStr);
        for (int i = 0; i <= years; i++) {
            year += i;
            for (FestivalDefault festivalDefault : festivalDefaults) {
                Festival festival = new Festival();
                festival.setDate(year + "-" + festivalDefault.getDate());
                festival.setName(festivalDefault.getName());
                festival.setType(festivalDefault.getType());
                festivals.add(festival);
            }
            //特殊: 母亲节5月第二个星期日

            // 父亲节 6月第三个星期日
        }
        if (CollectionUtil.isNotEmpty(festivals)) {
            saveBatch(festivals);
        }
    }

    /**
     * 农历节日获取
     *
     * @param end 结束时间
     */
    private void getChinesFestival(DateTime end) {
        List<Festival> festivals = new ArrayList<>();
        List<FestivalDefault> festivalDefaults = festivalDefaultService.getByType(FestivalDefaultType.chines.getKey());
        Map<String, FestivalDefault> map = new HashMap<>(8);
        if (CollectionUtil.isNotEmpty(festivalDefaults)) {
            for (FestivalDefault f : festivalDefaults) {
                map.put(f.getDate(), f);
            }
        }
        DateTime now = DateTime.now();
        //清明节 公历 4月5日前后  除夕 春节前一天
        while (now.isAfter(end)) {
            now = DateUtil.offsetDay(now, 1);
            ChineseDate chineseDate = new ChineseDate(now);
            int month = chineseDate.getMonth();
            int day = chineseDate.getDay();
            String key = (month < 9 ? "0" + month : String.valueOf(month)) + "-" + (day < 9 ? "0" + day : String.valueOf(day));
            FestivalDefault festivalDefault = map.get(key);
            if (festivalDefault != null) {
                Festival festival = new Festival();
                festival.setType(festivalDefault.getType());
                festival.setDate(DateUtil.formatDate(now));
                festival.setName(festivalDefault.getName());
                festivals.add(festival);
                //如果是春节,记录前一天为除夕
                if ("春节".equals(festival.getName())) {
                    Festival chuxi = new Festival();
                    chuxi.setType(festivalDefault.getType());
                    chuxi.setDate(DateUtil.formatDate(DateUtil.offsetDay(now, -1)));
                    chuxi.setName("除夕");
                    festivals.add(chuxi);
                }
            }
        }
        saveBatch(festivals);
    }
}
